#pragma once
#include <iostream>
#include <string>
#include <sys/ipc.h>
#include <cstdio>
#include <sys/shm.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <string.h>

const std::string path = "/home/jk/Linux-jk/PtoP_Com/Sharemem";
int projId = 0x666;
const int gsharesize = 4096;
const int gsharemode = 0666;

std::string ToHex(key_t k)
{
    char str[64];
    snprintf(str, sizeof(str), "0x%x", k);
    return str;
}

// 由于有很多类似的接口，封装
class ShareMemory
{
protected:
    void CreateShmHelper(int shmflg)
    {
        // 1.创建key
        _key = ::ftok(path.c_str(), projId);
        std::cout << "k : " << ToHex(_key) << std::endl;
        // 2.创建&&获取 新的共享内存
        _shmid = shmget(_key, gsharesize, shmflg);
        if (_shmid < 0)
        {
            // 创建共享内存失败
            std::cerr << "shmget error" << std::endl;
        }
        std::cout << "shmget success" << std::endl;
    }

public:
    ShareMemory() : _shmid(-1), _adder(nullptr),_key(0) {}
    void CreateShm() //创建新的共享内存
    {
        if (_shmid == -1)
            CreateShmHelper(IPC_CREAT | IPC_EXCL | gsharemode);
    }
    void GetShm()   //获取共享内存
    {
        CreateShmHelper(IPC_CREAT);
    }
    void AttchShm()
    {
        // 3. 挂载 共享内存和进程进行关联
        _adder = shmat(_shmid, nullptr, 0);
        if((long long)_adder == -1)
        std::cout << "attch done" << ToHex((long long)_adder) << std::endl;
    }
    void DattchShm()
    {   
        // 4. 去关联:
        if(_adder != nullptr)
        shmdt(_adder); // 解除挂载，nattch会减1（若Client卸载，nattch从1变为0）
        std::cout << "detach done: " << std::endl;
    }
    void DeleteShm()
    {
        // 5. 核心：调用shmctl删除共享内存（IPC_RMID = Remove ID）
        int ret = ::shmctl(_shmid, IPC_RMID, NULL);
        if (ret < 0)
        {
            std::cerr << "shmctl delete error" << std::endl;
        }
        std::cout << "shared memory deleted success (shmid: " << _shmid << ")" << std::endl;
    }
    ~ShareMemory() {}
    void* GetAdder(){
        return _adder;
    }
private:
    int _shmid;
    void *_adder;
    key_t _key;
};

ShareMemory shm;

//数据结构体
struct data{
    char status[32];
    char lasttime[48];
    char image[4000];   
};